package com.wangxin.study8.optional;

import java.util.Optional;

/**
 * @ClassName OptionalTest
 * @Description Optional学习
 * 这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true，调用get()方法会返回该对象。
 * @Author Wangxin
 * @Date 2019-03-16 17:12
 * @Version 1.0
 **/
public class OptionalTest {
    public static void main(String[] args) {
        /**
         * of
         * 返回一个指定非null值的Optional。
         * of方法通过工厂方法创建Optional类。
         * 需要注意的是，创建对象时传入的参数不能为null。如果传入参数为null，则抛出NullPointerException 。
         */
        Optional<String> name = Optional.of("WangXinJoJo");
        //抛出异常，抛出NullPointerException.
        Optional<String> nameNull = Optional.of(null);

        /**
         * ofNullable
         * 如果为非空，返回 Optional 描述的指定值，否则返回空的 Optional。
         * ofNullable与of方法相似，唯一的区别是可以接受参数为null的情况。
         * empty==null
         */
        Optional empty = Optional.ofNullable(null);

        /**
         * ifPresent
         * 如果值存在则使用该值调用 consumer , 否则不做任何事情。
         * 如果Optional实例有值，调用ifPresent()可以接受接口段或lambda表达式。
         */
        name.ifPresent(t->{
            System.out.println(t);
        });
        name.ifPresent(System.out::println);

        /**
         * orElse
         * 如果有值则将其返回，否则返回指定的其它值。
         * 如果Optional实例有值则将其返回，否则返回orElse方法传入的参数。
         */
        //输出There is no value present!
        System.out.println(empty.orElse("There is no value present!"));
        //输出WangXin
        System.out.println(name.orElse("There is some value!"));

        /**
         * orElseGet
         * orElseGet与orElse方法类似，区别在于得到的默认值。
         * orElse方法将传入的字符串作为默认值，orElseGet方法可以接受Supplier接口的实现用来生成默认值。
         */
        //输出Default Value
        System.out.println(empty.orElseGet(()->"Default Value"));
        //输出WangXin
        System.out.println(name.orElseGet(()->"Default Value"));

        /**
         * map
         * 如果有值，则对其执行调用mapping函数得到返回值。
         * 如果返回值不为null，则创建包含mapping返回值的Optional作为map方法返回值，否则返回空Optional。
         */
        Optional<String> uppermap = name.map(t->t.toUpperCase());
        System.out.println(uppermap.orElse("No value found"));

        /**
         * flatMap
         * 如果有值，为其执行mapping函数返回Optional类型返回值，否则返回空Optional。
         * flatMap与map（Funtion）方法类似，
         * 区别在于flatMap中的mapper返回值必须是Optional。
         * 调用结束时，flatMap不会对结果用Optional封装。
         * flatMap方法与map方法类似，区别在于mapping函数的返回值不同。
         * map方法的mapping函数返回值可以是任何类型T，而flatMap方法的mapping函数必须是Optional。
         */
        uppermap = name.flatMap(t->Optional.of(t.toUpperCase()));
        System.out.println(uppermap.orElse("No value found"));

        /**
         * filter
         * 如果有值并且满足断言条件返回包含该值的Optional，否则返回空Optional
         */
        Optional<String> longname = name.filter(t->t.length()>6);
        System.out.println(longname.orElse("The name is less than 6 characters"));
        Optional<String> anotherName = Optional.of("jojo");
        Optional<String> shortNmae = anotherName.filter(t->t.length()>6);
        System.out.println(shortNmae.orElse("The name is less than 6 characters"));


        //of（）：为非null的值创建一个Optional
        Optional<String> optional = Optional.of("bam");
        // isPresent（）： 如果值存在返回true，否则返回false
        optional.isPresent();           // true
        //get()：如果Optional有值则将其返回，否则抛出NoSuchElementException
        optional.get();                 // "bam"
        //orElse（）：如果有值则将其返回，否则返回指定的其它值
        optional.orElse("fallback");    // "bam"
        //ifPresent（）：如果Optional实例有值则为其调用consumer，否则不做处理
        optional.ifPresent((s) -> System.out.println(s.charAt(0)));     // "b"

    }
}
